source('../env.R')

Generate Worldwide Distributions for all Columbidae

Read in the Birdlife Distribution

Birdlife dataset “Bird Species Distribution Maps of the World.” (2020).

A download of the birdlife distributions can be requested from here: https://datazone.birdlife.org/species/requestdis

BIRDLIFE_DISTRIBUTIONS = '/Users/james/Dropbox/PhD/BirdLife/Distribution/SppDataRequest_columbidae/SppDataRequest.shp'
birdlife = st_read(BIRDLIFE_DISTRIBUTIONS)
Reading layer `SppDataRequest' from data source `/Users/james/Dropbox/PhD/BirdLife/Distribution/SppDataRequest_columbidae/SppDataRequest.shp' using driver `ESRI Shapefile'
Simple feature collection with 529 features and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -180 ymin: -55.72332 xmax: 180 ymax: 70.13647
Geodetic CRS:  WGS 84
head(birdlife)
Simple feature collection with 6 features and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -180 ymin: -46.62738 xmax: 180 ymax: 65.45892
Geodetic CRS:  WGS 84
     SISID            SCI_NAME PRESENCE ORIGIN SEASONAL
1 22690059   Raphus cucullatus        5      1        1
2 22690062 Pezophaps solitaria        5      1        1
3 22690066       Columba livia        1      3        1
4 22690066       Columba livia        1      1        1
5 22690074   Columba rupestris        1      1        3
6 22690074   Columba rupestris        1      1        1
                                                                                                                                          SOURCE
1 Cheke, 1987; Hachisuka, 1953; Livezey, 1993; Owadally, 1979; Strickland and Melville, 1848; Temple, 1977 ;Roberts and Solow, 2004; Cheke, 2006
2                                                                                                     Cheke, 1987; Cowles, 1987; Hachisuka, 1953
3                                            Cramp, 1997; Rasmussen, 2004; Flint, 1984; Ding, 2001; Porter, 1996; Urban, 1986; Gibbs et al, 2001
4                                Cramp, 1997; Rasmussen, 2004; Flint, 1984; Ding, 2001; Porter, 1996; Urban, 1986; Gibbs et al, 2001; eBird 2019
5                                                                                                                          Grimmett et al., 2008
6                                       Gibbs et al., 2001; Rasmussen and Anderton, 2005; Spierenburg, 2005; Grimmett et al., 2008; Brazil, 2009
                                                                        COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD
1                                         Philip Martin (BirdLife International)         0      <NA>      <NA>     <NA>          0
2                                         Philip Martin (BirdLife International)         0      <NA>      <NA>     <NA>          0
3                                                         BirdLife International         0      <NA>      <NA>     <NA>          0
4 Lynda Donaldson (BirdLife International); Donal Smith (BirdLife International)         0      <NA>      <NA>     <NA>          0
5                                            Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
6                                            Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
                                                       CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
1 BirdLife International and Handbook of the Birds of the World       2010       2016  2022.2 MULTIPOLYGON (((57.64288 -2...
2 BirdLife International and Handbook of the Birds of the World       2010       2016  2022.2 MULTIPOLYGON (((63.47229 -1...
3 BirdLife International and Handbook of the Birds of the World       2006       2016  2022.2 MULTIPOLYGON (((5.383484 53...
4 BirdLife International and Handbook of the Birds of the World       2016       2019  2022.2 MULTIPOLYGON (((88.3183 21....
5 BirdLife International and Handbook of the Birds of the World       2010       2016  2022.2 MULTIPOLYGON (((75.19348 36...
6 BirdLife International and Handbook of the Birds of the World       2010       2016  2022.2 MULTIPOLYGON (((120.8933 36...

Read in the Birdlife Taxonomy

Load the birdlife taxonomy to find Columbidae species.

The taxonomy can be downloaded here: https://datazone.birdlife.org/species/taxonomy

st_crs(birdlife)
Coordinate Reference System:
  User input: WGS 84 
  wkt:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["latitude",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["longitude",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    ID["EPSG",4326]]
BIRDLIFE_TAXONOMY = '/Users/james/Dropbox/PhD/BirdLife/Taxonomy/Handbook of the Birds of the World and BirdLife International Digital Checklist of the Birds of the World_Version_8.xlsx'
birdlifeTaxonomyWb = read_excel(BIRDLIFE_TAXONOMY)
New names:
birdlifeTaxonomyWb
names(birdlifeTaxonomyWb) <- birdlifeTaxonomyWb[2,]
Warning: The `value` argument of `names<-` must be a character vector as of tibble 3.0.0.
birdlifeTaxonomy <- birdlifeTaxonomyWb[-2,]
birdlifeTaxonomy
birdlifeColumbidae = birdlifeTaxonomy[!is.na(birdlifeTaxonomy$Order) & birdlifeTaxonomy$Order == 'COLUMBIFORMES', c('SISRecID', 'Scientific name', 'Common name', 'Synonyms')]
names(birdlifeColumbidae) = c('birdlife_id', 'species_name', 'common_name', 'synonyms')
birdlifeColumbidae

Check to see if we have any missing distributions

birdlifeColumbidae[!(birdlifeColumbidae$species_name %in% birdlife$SCI_NAME),]

Most of those species are extinct. The species not extinct are: * Nesoenas picturata (?) * Geotrygon lawrencii (previously considered conspecific of Zentrygon carrikeri) - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/22729899 * Gallicolumba beccarii - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/22691066 * Geophaps ferruginea - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/22725184 - lumped in with G. plumifera * Ducula constans - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/ducula-constans * Ducula salvadorii - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/45448199 - previously lumped as D. pinon * Ptilinopus subgularis - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/22691351 * Ramphiculus meridionalis - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/22728045 - previously placed in the genus Ptilinopus and lumped as P. fischeri * Stigmatopelia chinensis - not a species recognised by birdlife http://datazone.birdlife.org/species/factsheet/stigmatopelia-chinensis

Extinct species: * Caloenas maculata * Nesoenas rostrata * Gallicolumba norfolciensis

Missing Nesoenas picturata

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Nesoenas picturata',]
birdlife[birdlife$SCI_NAME == 'Nesoenas picturatus',]
Simple feature collection with 2 features and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 43.19138 ymin: -25.60895 xmax: 72.49316 ymax: -3.71152
Geodetic CRS:  WGS 84
      SISID            SCI_NAME PRESENCE ORIGIN SEASONAL                                                                              SOURCE
84 22690364 Nesoenas picturatus        1      1        1 Langrand, 1990; Gibbs et al, 2001; Skerrett et al, 2001; Roger Safford, pers. comm.
85 22690364 Nesoenas picturatus        1      3        1                       Sinclair, 1998; Gibbs et al, 2001; Roger Safford, pers. comm.
                                               COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD
84 Richard Johnson; Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
85 Richard Johnson; Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
                                                        CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
84 BirdLife International and Handbook of the Birds of the World       2013       2016  2022.2 MULTIPOLYGON (((44.41069 -1...
85 BirdLife International and Handbook of the Birds of the World       2013       2016  2022.2 MULTIPOLYGON (((55.45396 -2...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '22690364',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '22690364'] = 'Columba picturata; Streptopelia picturata,Nesoenas picturata'

Missing Geotrygon lawrencii

Previously considered conspecific of Zentrygon carrikeri

http://datazone.birdlife.org/species/factsheet/22729899

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Geotrygon lawrencii',]
birdlife[birdlife$SCI_NAME == 'Zentrygon carrikeri',]
Simple feature collection with 1 feature and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -95.2132 ymin: 18.29449 xmax: -94.71039 ymax: 18.56891
Geodetic CRS:  WGS 84
       SISID            SCI_NAME PRESENCE ORIGIN SEASONAL                 SOURCE               COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD
212 22690901 Zentrygon carrikeri        1      1        1 BirdLife International BirdLife International         0      <NA>      <NA>     <NA>          0
                                                         CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
212 BirdLife International and Handbook of the Birds of the World       1999       2020  2022.2 MULTIPOLYGON (((-94.8493 18...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '22690901',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '22690901'] = 'Geotrygon carrikeri,Geotrygon lawrencii'

Missing Gallicolumba beccarii

http://datazone.birdlife.org/species/factsheet/22691066

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Gallicolumba beccarii',]
birdlife[birdlife$SCI_NAME == 'Pampusana beccarii',]
Simple feature collection with 1 feature and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 132.1133 ymin: -10.22302 xmax: 149.9799 ymax: -0.4857788
Geodetic CRS:  WGS 84
       SISID           SCI_NAME PRESENCE ORIGIN SEASONAL                                                                           SOURCE
504 60444792 Pampusana beccarii        1      1        1 Coates, 1985; del Hoyo et al, 1997; Doughty, 1999; Gibbs et al, 2001; Mayr, 2001
                                                COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD
504 Richard Johnson; Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
                                                         CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
504 BirdLife International and Handbook of the Birds of the World       2013       2016  2022.2 MULTIPOLYGON (((136.7927 -3...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '60444792',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '60444792'] = 'Gallicolumba beccarii'

Missing Geophaps ferruginea

http://datazone.birdlife.org/species/factsheet/22725184 - lumped in with G. plumifera

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Geophaps ferruginea',]
birdlife[birdlife$SCI_NAME == 'Geophaps plumifera',]
Simple feature collection with 1 feature and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 113.5466 ymin: -28.14721 xmax: 145.6556 ymax: -13.85436
Geodetic CRS:  WGS 84
       SISID           SCI_NAME PRESENCE ORIGIN SEASONAL                                                                       SOURCE
140 22690682 Geophaps plumifera        1      1        1 del Hoyo et al, 1999; Morcombe, 2000; Gibbs et al, 2001; Barrett et al, 2003
                                                                                COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD
140 Mia Derhe; Joe Taylor (BirdLife International); Donal Smith (BirdLife International)         0      <NA>      <NA>     <NA>          0
                                                         CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
140 BirdLife International and Handbook of the Birds of the World       2019       2019  2022.2 MULTIPOLYGON (((135.6649 -1...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '22690682',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '22690682'] = 'Geophaps ferruginea'

Missing Ducula constans

http://datazone.birdlife.org/species/factsheet/ducula-constans

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Ducula constans',]
birdlife[birdlife$SCI_NAME == 'Ducula spilorrhoa',]
Simple feature collection with 1 feature and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 123.8503 ymin: -21.95601 xmax: 154.2817 ymax: -0.6268331
Geodetic CRS:  WGS 84
       SISID          SCI_NAME PRESENCE ORIGIN SEASONAL
488 22733554 Ducula spilorrhoa        1      1        1
                                                                                                                                                       SOURCE
488 Rand and Gilliard, 1967; del Hoyo et al, 1997; Ding, 2001; Gibbs et al, 2001; Strange, 2001; Robson, 2002; Barrett et al, 2003; Robson, 2008; Myers, 2009
                                           COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD
488 Rob Martin, Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
                                                         CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
488 BirdLife International and Handbook of the Birds of the World       2014       2016  2022.2 MULTIPOLYGON (((137.8399 -5...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '22733554',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '22733554'] = 'Ducula constans'

Missing Ducula salvadorii

http://datazone.birdlife.org/species/factsheet/45448199 - previously lumped as D. pinon

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Ducula salvadorii',]
birdlife[birdlife$SCI_NAME == 'Ducula pinon',]
Simple feature collection with 1 feature and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 129.7127 ymin: -11.65778 xmax: 154.2817 ymax: 0.03948975
Geodetic CRS:  WGS 84
       SISID     SCI_NAME PRESENCE ORIGIN SEASONAL                                                               SOURCE                            COMPILER
389 22691760 Ducula pinon        1      1        1 Coates, 1985; Strange, 2001; Gibbs et al, 2001; del Hoyo et al, 1997 Jemma Vine (BirdLife International)
    DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD                                                      CITATION YRCOMPILED YRMODIFIED VERSION
389         0      <NA>      <NA>     <NA>          0 BirdLife International and Handbook of the Birds of the World       2013       2023  2023.1
                          geometry
389 MULTIPOLYGON (((144.2385 -3...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '22691760',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '22691760'] = 'Ducula salvadorii'

Missing Ptilinopus subgularis

http://datazone.birdlife.org/species/factsheet/22691351

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Ptilinopus subgularis',]
birdlife[birdlife$SCI_NAME == 'Ramphiculus subgularis',]
Simple feature collection with 2 features and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 122.7788 ymin: -1.767872 xmax: 123.6186 ymax: -1.15033
Geodetic CRS:  WGS 84
       SISID               SCI_NAME PRESENCE ORIGIN SEASONAL                                                        SOURCE                            COMPILER
466 22728146 Ramphiculus subgularis        1      1        1 Davidson et al, 1995; del Hoyo et al, 1997; Gibbs et al, 2001 Joe Taylor (BirdLife International)
467 22728146 Ramphiculus subgularis        1      1        1 Davidson et al, 1995; del Hoyo et al, 1997; Gibbs et al, 2001 Joe Taylor (BirdLife International)
    DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD                                                      CITATION YRCOMPILED YRMODIFIED VERSION
466         0      <NA>      <NA>     <NA>          0 BirdLife International and Handbook of the Birds of the World       2012       2016  2022.2
467         0      <NA>      <NA>     <NA>          0 BirdLife International and Handbook of the Birds of the World       2012       2016  2022.2
                          geometry
466 MULTIPOLYGON (((123.1666 -1...
467 MULTIPOLYGON (((123.1666 -1...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '22728146',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '22728146'] = 'Ptilinopus subgularis'

Missing Ramphiculus meridionalis

http://datazone.birdlife.org/species/factsheet/22728045 - previously placed in the genus Ptilinopus and lumped as P. fischeri

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Ramphiculus meridionalis',]
birdlife[birdlife$SCI_NAME == 'Ramphiculus fischeri',]
Simple feature collection with 1 feature and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 118.9495 ymin: -5.448394 xmax: 125.0379 ymax: 1.47724
Geodetic CRS:  WGS 84
       SISID             SCI_NAME PRESENCE ORIGIN SEASONAL            SOURCE                            COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM
303 22691332 Ramphiculus fischeri        1      1        1 Gibbs et al, 2001 Jemma Vine (BirdLife International)         0      <NA>      <NA>     <NA>
    GENERALISD                                                      CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
303          0 BirdLife International and Handbook of the Birds of the World       2023       2023  2023.1 MULTIPOLYGON (((120.1059 -1...
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '22691332',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '22691332'] = 'Ramphiculus meridionalis'

Missing Stigmatopelia chinensis

birdlifeColumbidae[birdlifeColumbidae$species_name == 'Stigmatopelia chinensis',]
birdlife[birdlife$SCI_NAME == 'Spilopelia chinensis',]
Simple feature collection with 2 features and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -180 ymin: -43.24591 xmax: 180 ymax: 40.87189
Geodetic CRS:  WGS 84
       SISID             SCI_NAME PRESENCE ORIGIN SEASONAL
506 60482887 Spilopelia chinensis        1      3        1
507 60482887 Spilopelia chinensis        1      1        1
                                                                                                           SOURCE
506                   Pratt, 1987; Higgins & Davies, 1996; del Hoyo et al, 1997; Gibbs et al, 2001; Strange, 2001
507 Pratt, 1987; del Hoyo et al, 1997; Doughty, 1999; Ding, 2001; Gibbs et al, 2001; Rasmussen and Anderton, 2005
                                                COMPILER DATA_SENS SENS_COMM DIST_COMM TAX_COMM GENERALISD
506 Richard Johnson; Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
507 Richard Johnson; Joe Taylor (BirdLife International)         0      <NA>      <NA>     <NA>          0
                                                         CITATION YRCOMPILED YRMODIFIED VERSION                       geometry
506 BirdLife International and Handbook of the Birds of the World       2013       2016  2022.2 MULTIPOLYGON (((144.7167 -1...
507 BirdLife International and Handbook of the Birds of the World       2013       2016  2022.2 MULTIPOLYGON (((88.3183 21....
birdlifeColumbidae[birdlifeColumbidae$birdlife_id == '60482887',]

Already present, update synonyms

birdlifeColumbidae$synonyms[birdlifeColumbidae$birdlife_id == '60482887'] = 'Streptopelia chinensis,Stigmatopelia chinensis'

Store Birdlife taxonomy

write_csv(birdlifeColumbidae[birdlifeColumbidae$species_name %in% birdlife$SCI_NAME,], filename(BIRDLIFE_WORKING_OUTPUT_DIR, 'taxonomy.csv'))
birdlifeColumbidae = read_csv(filename(BIRDLIFE_WORKING_OUTPUT_DIR, 'taxonomy.csv'))
Rows: 415 Columns: 4── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): species_name, common_name, synonyms
dbl (1): birdlife_id
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(birdlifeColumbidae)

Filter Birdlife Distributions to only Columbidae

Do we have any distributions not in our taxonomy?

birdlife[!(birdlife$SCI_NAME %in% birdlifeColumbidae$species_name),]
Simple feature collection with 0 features and 16 fields
Bounding box:  xmin: NA ymin: NA xmax: NA ymax: NA
Geodetic CRS:  WGS 84
 [1] SISID      SCI_NAME   PRESENCE   ORIGIN     SEASONAL   SOURCE     COMPILER   DATA_SENS  SENS_COMM  DIST_COMM  TAX_COMM   GENERALISD CITATION   YRCOMPILED
[15] YRMODIFIED VERSION    geometry  
<0 rows> (or 0-length row.names)
COLUMBIDAE_WORLD_DISTRIBUTIONS = filename(BIRDLIFE_WORKING_OUTPUT_DIR, "columbidae_world.shp")
write_sf(birdlife, COLUMBIDAE_WORLD_DISTRIBUTIONS)
Warning: GDAL Message 1: Value 154619350 of field SISID of feature 519 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 154619546 of field SISID of feature 520 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 154625310 of field SISID of feature 521 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 154625453 of field SISID of feature 522 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 154625942 of field SISID of feature 523 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 200093329 of field SISID of feature 524 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 200094385 of field SISID of feature 525 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 219582631 of field SISID of feature 526 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 232609896 of field SISID of feature 527 not successfully written. Possibly due to too larger number with respect to field widthWarning: GDAL Message 1: Value 232610475 of field SISID of feature 528 not successfully written. Possibly due to too larger number with respect to field width
columbidaeDistribution = read_sf(COLUMBIDAE_WORLD_DISTRIBUTIONS)

Free up memory by removing birdlife data from workspace

rm(birdlife)
rm(birdlifeTaxonomy)
rm(birdlifeTaxonomy_tmp)
Warning: object 'birdlifeTaxonomy_tmp' not found
rm(birdlifeTaxonomyWb)
rm(birdlifeTaxonomyWb_Sheets)
Warning: object 'birdlifeTaxonomyWb_Sheets' not found
st_crs(columbidaeDistribution)
Coordinate Reference System:
  User input: WGS 84 
  wkt:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["latitude",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["longitude",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    ID["EPSG",4326]]

Create intersection of Columbidae Distributions with Urban Spaces

Read in our initial city vectors, we will join these to our checklists

initial_city_selection = read_sf(filename(mkdir(GEO_WORKING_OUTPUT_DIR, 'cities'), 'initial_selection.shp'))
st_crs(initial_city_selection)
Coordinate Reference System:
  User input: WGS 84 
  wkt:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["latitude",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["longitude",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    ID["EPSG",4326]]
sf::sf_use_s2(FALSE)

urban_columbidae_distributions = st_join(initial_city_selection, columbidaeDistribution) 
although coordinates are longitude/latitude, st_intersects assumes that they are planar
urban_columbidae_distributions
Simple feature collection with 6633 features and 20 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -158.043 ymin: -38.20685 xmax: 174.9891 ymax: 60.3276
Geodetic CRS:  WGS 84

Check birdlife distribution data

Species with unknown presence?

urban_columbidae_distributions[urban_columbidae_distributions$PRESENCE > 5, c('SCI_NAME', 'city_name', 'city_id')]
Simple feature collection with 1 feature and 3 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 116.0291 ymin: -8.698981 xmax: 116.27 ymax: -8.479668
Geodetic CRS:  WGS 84

Any extinct species?

urban_columbidae_distributions[urban_columbidae_distributions$PRESENCE == 5, c('SCI_NAME', 'city_name', 'city_id')]
Simple feature collection with 38 features and 3 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -98.74208 ymin: -20.33485 xmax: 57.54632 ymax: 49.96685
Geodetic CRS:  WGS 84

Possibly Extinct species

urban_columbidae_distributions[urban_columbidae_distributions$PRESENCE == 4, c('SCI_NAME', 'city_name', 'city_id')]
Simple feature collection with 40 features and 3 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -82.49902 ymin: -25.60243 xmax: 125.6809 ymax: 23.18014
Geodetic CRS:  WGS 84

Map seasonal and origin to string values

urban_columbidae_distributions$seasonal_desc = "Unknown Code"
urban_columbidae_distributions$seasonal_desc[urban_columbidae_distributions$SEASONAL == "1"] = "Resident"
urban_columbidae_distributions$seasonal_desc[urban_columbidae_distributions$SEASONAL == "2"] = "Breeding Season" 
urban_columbidae_distributions$seasonal_desc[urban_columbidae_distributions$SEASONAL == "3"] = "Non-breeding Season" 
urban_columbidae_distributions$seasonal_desc[urban_columbidae_distributions$SEASONAL == "4"] = "Passage" 
urban_columbidae_distributions$seasonal_desc[urban_columbidae_distributions$SEASONAL == "5"] = "Seasonal occurence uncertain"
urban_columbidae_distributions$origin_desc = "Unknown Code"
urban_columbidae_distributions$origin_desc[urban_columbidae_distributions$ORIGIN == "1"] = "Native"
urban_columbidae_distributions$origin_desc[urban_columbidae_distributions$ORIGIN == "2"] = "Reintroduced" 
urban_columbidae_distributions$origin_desc[urban_columbidae_distributions$ORIGIN == "3"] = "Introduced" 
urban_columbidae_distributions$origin_desc[urban_columbidae_distributions$ORIGIN == "4"] = "Vagrant" 
urban_columbidae_distributions$origin_desc[urban_columbidae_distributions$ORIGIN == "5"] = "Origin Uncertain"
urban_columbidae_distributions$origin_desc[urban_columbidae_distributions$ORIGIN == "6"] = "Assisted Colonisation"
urban_columbidae_distributions$presence_desc = "Unknown Code"
urban_columbidae_distributions$presence_desc[urban_columbidae_distributions$PRESENCE == "1"] = "Extant"
urban_columbidae_distributions$presence_desc[urban_columbidae_distributions$PRESENCE == "2"] = "Probably Extant" 
urban_columbidae_distributions$presence_desc[urban_columbidae_distributions$PRESENCE == "3"] = "Possibly Extant" 
urban_columbidae_distributions$presence_desc[urban_columbidae_distributions$PRESENCE == "4"] = "Possibly Extinct" 
urban_columbidae_distributions$presence_desc[urban_columbidae_distributions$PRESENCE == "5"] = "Extinct"
urban_columbidae_distributions$presence_desc[urban_columbidae_distributions$PRESENCE == "6"] = "Presence Uncertain"
cache_urban_columbidae_distributions = filename(BIRDLIFE_WORKING_OUTPUT_DIR, 'urban_distributions_birdlife_only.csv')
write_csv(urban_columbidae_distributions, cache_urban_columbidae_distributions)
urban_columbidae_distributions = read_csv(cache_urban_columbidae_distributions)
Rows: 6633 Columns: 24── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): city_name, geometry, SCI_NAME, SOURCE, COMPILER, DIST_COMM, TAX_COMM, CITATION, seasonal_desc, origin_desc, presence_desc
dbl (12): city_id, pop_2015, bu_2015, SISID, PRESENCE, ORIGIN, SEASONAL, DATA_SENS, GENERALISD, YRCOMPILED, YRMODIFIED, VERSION
lgl  (1): SENS_COMM
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Missing North American distribution of Streptopelia decaocto and Columba Livia

Birdlife is missing the recent invasion of Streptopelia decaocto into North America. We supplement the data for Streptopelia decaocto with the range from eBird’s Status and Trends dataset.

This data can be downloaded here: https://science.ebird.org/en/status-and-trends/species/eucdov/downloads

The country boundandaries can be downloaded from the world bank here: https://datacatalog.worldbank.org/search/dataset/0038272/World-Bank-Official-Boundaries

COUNTRY_BOUNDARIES = '/Users/james/Dropbox/PhD/WorldBank_countries_Admin0_10m/WB_countries_Admin0_10m.shp'
world_map = st_simplify(st_read(COUNTRY_BOUNDARIES), dTolerance = 0.02)
Reading layer `WB_countries_Admin0_10m' from data source `/Users/james/Dropbox/PhD/WorldBank_countries_Admin0_10m/WB_countries_Admin0_10m.shp' using driver `ESRI Shapefile'
Simple feature collection with 251 features and 52 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -180 ymin: -59.47275 xmax: 180 ymax: 83.6341
Geodetic CRS:  WGS 84
Warning: st_simplify does not correctly simplify longitude/latitude data, dTolerance needs to be in decimal degrees

Collared Dove

Existing range from Birdlife

sf::sf_use_s2(FALSE)
coldov_vect = st_simplify(columbidaeDistribution[columbidaeDistribution$SCI_NAME == 'Streptopelia decaocto', c('PRESENCE')], dTolerance = 0.02)
Warning: st_simplify does not correctly simplify longitude/latitude data, dTolerance needs to be in decimal degrees
ggplot() +  
  geom_sf(data = world_map, aes(geometry = geometry)) +
  geom_sf(data = coldov_vect, aes(geometry = geometry), fill = "red")

Range from eBird

EBIRD_EUCDOV_RANGE = '/Users/james/Dropbox/PhD/eBird/eucdov_range_2022/eucdov_range_2022.gpkg'
eucdov_range_vect = st_read(EBIRD_EUCDOV_RANGE)
Reading layer `range' from data source `/Users/james/Dropbox/PhD/eBird/eucdov_range_2022/eucdov_range_2022.gpkg' using driver `GPKG'
Simple feature collection with 1 feature and 8 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -129.1392 ymin: 6.847467 xmax: 128.6997 ymax: 60.44009
Geodetic CRS:  WGS 84
ggplot() +  
  geom_sf(data = world_map, aes(geometry = geometry)) +
  geom_sf(data = eucdov_range_vect["scientific_name"], aes(geometry = geom), fill = "red")

Extract cities from eBird range

sf::sf_use_s2(FALSE)

existing_eucdov_cities = urban_columbidae_distributions$city_id[urban_columbidae_distributions$SCI_NAME == 'Streptopelia decaocto']

eucdov_distribution = st_join(initial_city_selection, eucdov_range_vect) 
although coordinates are longitude/latitude, st_intersects assumes that they are planar
eucdov_distribution[!is.na(eucdov_distribution$species_code) & !(eucdov_distribution$city_id %in% existing_eucdov_cities),]
Simple feature collection with 116 features and 12 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -123.2852 ymin: 16.69475 xmax: 126.8399 ymax: 51.22359
Geodetic CRS:  WGS 84
missing_eucdov_cities = data.frame(
    species_name = 'Streptopelia decaocto', 
    city_id = eucdov_distribution$city_id[!is.na(eucdov_distribution$species_code) & !(eucdov_distribution$city_id %in% existing_eucdov_cities)],
    city_name= eucdov_distribution$city_name[!is.na(eucdov_distribution$species_code) & !(eucdov_distribution$city_id %in% existing_eucdov_cities)],
    origin = 'Introduced',
    seasonal = 'Resident',
    presence = 'Extant'
)
missing_eucdov_cities

Rock dove

Existing range from Birdlife

sf::sf_use_s2(FALSE)
rocdov_vect = st_simplify(columbidaeDistribution[columbidaeDistribution$SCI_NAME == 'Columba livia', c('PRESENCE')], dTolerance = 0.02)
Warning: st_simplify does not correctly simplify longitude/latitude data, dTolerance needs to be in decimal degrees
ggplot() +  
  geom_sf(data = world_map, aes(geometry = geometry)) +
  geom_sf(data = rocdov_vect, aes(geometry = geometry), fill = "red")

Range from eBird

sf::sf_use_s2(FALSE)

existing_rocpig_cities = urban_columbidae_distributions$city_id[urban_columbidae_distributions$SCI_NAME == 'Columba livia']

rocpig_distribution = st_join(initial_city_selection, rocpig_range_vect) 
although coordinates are longitude/latitude, st_intersects assumes that they are planar
rocpig_distribution[!is.na(rocpig_distribution$species_code) & !(rocpig_distribution$city_id %in% existing_rocpig_cities),]
Simple feature collection with 453 features and 12 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -158.043 ymin: -38.11825 xmax: 141.5939 ymax: 53.66794
Geodetic CRS:  WGS 84
missing_rocpig_cities = data.frame(
    species_name = 'Columba livia', 
    city_id = rocpig_distribution$city_id[!is.na(rocpig_distribution$species_code) & !(rocpig_distribution$city_id %in% existing_rocpig_cities)],
    city_name= rocpig_distribution$city_name[!is.na(rocpig_distribution$species_code) & !(rocpig_distribution$city_id %in% existing_rocpig_cities)],
    origin = 'Introduced',
    seasonal = 'Resident',
    presence = 'Extant'
)
missing_rocpig_cities

Add Spotted dove’s expanded range into China

Existing range from Birdlife

Range from eBird

EBIRD_SPODOV_RANGE = '/Users/james/Dropbox/PhD/eBird/spodov_range_2022/spodov_range_2022.gpkg'
spodov_range_vect = st_read(EBIRD_SPODOV_RANGE)
Reading layer `range' from data source `/Users/james/Dropbox/PhD/eBird/spodov_range_2022/spodov_range_2022.gpkg' using driver `GPKG'
Simple feature collection with 1 feature and 8 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -180 ymin: -43.72339 xmax: 180 ymax: 44.8739
Geodetic CRS:  WGS 84
ggplot() +  
  geom_sf(data = world_map, aes(geometry = geometry)) +
  geom_sf(data = spodov_range_vect["scientific_name"], aes(geometry = geom), fill = "red")

sf::sf_use_s2(FALSE)

existing_spodov_cities = urban_columbidae_distributions$city_id[urban_columbidae_distributions$SCI_NAME %in% c('Spilopelia chinensis','Spilopelia suratensis','Patagioenas albipennis')]

spodov_distribution = st_join(initial_city_selection, spodov_range_vect) 
although coordinates are longitude/latitude, st_intersects assumes that they are planar

spodov_distribution[!is.na(spodov_distribution$species_code) & !(spodov_distribution$city_id %in% existing_spodov_cities),]
Simple feature collection with 29 features and 12 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 70.54817 ymin: 27.96718 xmax: 125.8892 ymax: 43.98709
Geodetic CRS:  WGS 84
missing_spodov_cities = data.frame(
    species_name = 'Spilopelia chinensis', 
    city_id = spodov_distribution$city_id[!is.na(spodov_distribution$species_code) & !(spodov_distribution$city_id %in% existing_spodov_cities)],
    city_name= spodov_distribution$city_name[!is.na(spodov_distribution$species_code) & !(spodov_distribution$city_id %in% existing_spodov_cities)],
    origin = 'Introduced',
    seasonal = 'Resident',
    presence = 'Extant'
)
missing_spodov_cities

Store regional pool result

urban_distribution = rbind(
  data.frame(
    species_name = urban_columbidae_distributions$binomil, 
    city_id = urban_columbidae_distributions$city_id,
    city_name= urban_columbidae_distributions$city_name,
    origin = urban_columbidae_distributions$origin_desc,
    seasonal = urban_columbidae_distributions$seasonal_desc,
    presence = urban_columbidae_distributions$presence_desc
  ),
 rbind(missing_eucdov_cities, rbind(missing_rocpig_cities, missing_spodov_cities))
)
Warning: Unknown or uninitialised column: `binomil`.Error in data.frame(species_name = urban_columbidae_distributions$binomil,  : 
  arguments imply differing number of rows: 0, 6633

Examine result

urban_distribution = read_csv(BIRDLIFE_URBAN_DISTRIBUTION)
Rows: 7231 Columns: 6── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): species_name, city_name, origin, seasonal, presence
dbl (1): city_id
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Species in Manchester’s regional pool

urban_distribution %>% filter(city_name == 'Manchester') 

Species in Miami’s regional pool

urban_distribution %>% filter(city_name == 'Miami') 

Cities with Common Woodpigeon in regional pool

urban_distribution %>% filter(species_name == 'Columba palumbus')

Cities with Collared Dove in regional pool

urban_distribution %>% filter(species_name == 'Streptopelia decaocto')

Regional pool sizes

urban_distribution %>% group_by(city_id, city_name) %>% summarise(pool_size = n()) %>% arrange(pool_size)
`summarise()` has grouped output by 'city_id'. You can override using the `.groups` argument.
“Bird Species Distribution Maps of the World.” 2020. BirdLife International; Handbook of the Birds of the World. http://datazone.birdlife.org/species/requestdis.
LS0tCnRpdGxlOiAiQ3JlYXRlIHJlZ2lvbmFsIHBvb2xzIHVzaW5nIEJpcmRMaWZlIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKYmlibGlvZ3JhcGh5OiAuLi9yZWYuYmliIAotLS0KCmBgYHtyfQpzb3VyY2UoJy4uL2Vudi5SJykKYGBgCgojIEdlbmVyYXRlIFdvcmxkd2lkZSBEaXN0cmlidXRpb25zIGZvciBhbGwgQ29sdW1iaWRhZQoKIyMgUmVhZCBpbiB0aGUgQmlyZGxpZmUgRGlzdHJpYnV0aW9uIApCaXJkbGlmZSBkYXRhc2V0IEBCaXJkbGlmZTIwMjAuCgpBIGRvd25sb2FkIG9mIHRoZSBiaXJkbGlmZSBkaXN0cmlidXRpb25zIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSBoZXJlOgpodHRwczovL2RhdGF6b25lLmJpcmRsaWZlLm9yZy9zcGVjaWVzL3JlcXVlc3RkaXMKCmBgYHtyfQpCSVJETElGRV9ESVNUUklCVVRJT05TID0gJy9Vc2Vycy9qYW1lcy9Ecm9wYm94L1BoRC9CaXJkTGlmZS9EaXN0cmlidXRpb24vU3BwRGF0YVJlcXVlc3RfY29sdW1iaWRhZS9TcHBEYXRhUmVxdWVzdC5zaHAnCmJpcmRsaWZlID0gc3RfcmVhZChCSVJETElGRV9ESVNUUklCVVRJT05TKQpoZWFkKGJpcmRsaWZlKQpgYGAKCiMjIFJlYWQgaW4gdGhlIEJpcmRsaWZlIFRheG9ub215CkxvYWQgdGhlIGJpcmRsaWZlIHRheG9ub215IHRvIGZpbmQgQ29sdW1iaWRhZSBzcGVjaWVzLgoKVGhlIHRheG9ub215IGNhbiBiZSBkb3dubG9hZGVkIGhlcmU6Cmh0dHBzOi8vZGF0YXpvbmUuYmlyZGxpZmUub3JnL3NwZWNpZXMvdGF4b25vbXkKCmBgYHtyfQpzdF9jcnMoYmlyZGxpZmUpCmBgYAoKYGBge3J9CkJJUkRMSUZFX1RBWE9OT01ZID0gJy9Vc2Vycy9qYW1lcy9Ecm9wYm94L1BoRC9CaXJkTGlmZS9UYXhvbm9teS9IYW5kYm9vayBvZiB0aGUgQmlyZHMgb2YgdGhlIFdvcmxkIGFuZCBCaXJkTGlmZSBJbnRlcm5hdGlvbmFsIERpZ2l0YWwgQ2hlY2tsaXN0IG9mIHRoZSBCaXJkcyBvZiB0aGUgV29ybGRfVmVyc2lvbl84Lnhsc3gnCmJpcmRsaWZlVGF4b25vbXlXYiA9IHJlYWRfZXhjZWwoQklSRExJRkVfVEFYT05PTVkpCmJpcmRsaWZlVGF4b25vbXlXYgpgYGAKCmBgYHtyfQpuYW1lcyhiaXJkbGlmZVRheG9ub215V2IpIDwtIGJpcmRsaWZlVGF4b25vbXlXYlsyLF0KYmlyZGxpZmVUYXhvbm9teSA8LSBiaXJkbGlmZVRheG9ub215V2JbLTIsXQpiaXJkbGlmZVRheG9ub215CmBgYAoKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZSA9IGJpcmRsaWZlVGF4b25vbXlbIWlzLm5hKGJpcmRsaWZlVGF4b25vbXkkT3JkZXIpICYgYmlyZGxpZmVUYXhvbm9teSRPcmRlciA9PSAnQ09MVU1CSUZPUk1FUycsIGMoJ1NJU1JlY0lEJywgJ1NjaWVudGlmaWMgbmFtZScsICdDb21tb24gbmFtZScsICdTeW5vbnltcycpXQpuYW1lcyhiaXJkbGlmZUNvbHVtYmlkYWUpID0gYygnYmlyZGxpZmVfaWQnLCAnc3BlY2llc19uYW1lJywgJ2NvbW1vbl9uYW1lJywgJ3N5bm9ueW1zJykKYmlyZGxpZmVDb2x1bWJpZGFlCmBgYAoKQ2hlY2sgdG8gc2VlIGlmIHdlIGhhdmUgYW55IG1pc3NpbmcgZGlzdHJpYnV0aW9ucwpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlWyEoYmlyZGxpZmVDb2x1bWJpZGFlJHNwZWNpZXNfbmFtZSAlaW4lIGJpcmRsaWZlJFNDSV9OQU1FKSxdCmBgYAoKTW9zdCBvZiB0aG9zZSBzcGVjaWVzIGFyZSBleHRpbmN0LiBUaGUgc3BlY2llcyBub3QgZXh0aW5jdCBhcmU6CiogTmVzb2VuYXMgcGljdHVyYXRhCSg/KQoqIEdlb3RyeWdvbiBsYXdyZW5jaWkgKHByZXZpb3VzbHkgY29uc2lkZXJlZCBjb25zcGVjaWZpYyBvZiBaZW50cnlnb24gY2FycmlrZXJpKSAtIG5vdCBhIHNwZWNpZXMgcmVjb2duaXNlZCBieSBiaXJkbGlmZSBodHRwOi8vZGF0YXpvbmUuYmlyZGxpZmUub3JnL3NwZWNpZXMvZmFjdHNoZWV0LzIyNzI5ODk5CiogR2FsbGljb2x1bWJhIGJlY2NhcmlpCS0gbm90IGEgc3BlY2llcyByZWNvZ25pc2VkIGJ5IGJpcmRsaWZlIGh0dHA6Ly9kYXRhem9uZS5iaXJkbGlmZS5vcmcvc3BlY2llcy9mYWN0c2hlZXQvMjI2OTEwNjYKKiBHZW9waGFwcyBmZXJydWdpbmVhIC0gbm90IGEgc3BlY2llcyByZWNvZ25pc2VkIGJ5IGJpcmRsaWZlIGh0dHA6Ly9kYXRhem9uZS5iaXJkbGlmZS5vcmcvc3BlY2llcy9mYWN0c2hlZXQvMjI3MjUxODQgLSBsdW1wZWQgaW4gd2l0aCBHLiBwbHVtaWZlcmEKKiBEdWN1bGEgY29uc3RhbnMgLSBub3QgYSBzcGVjaWVzIHJlY29nbmlzZWQgYnkgYmlyZGxpZmUgaHR0cDovL2RhdGF6b25lLmJpcmRsaWZlLm9yZy9zcGVjaWVzL2ZhY3RzaGVldC9kdWN1bGEtY29uc3RhbnMKKiBEdWN1bGEgc2FsdmFkb3JpaQkgLSBub3QgYSBzcGVjaWVzIHJlY29nbmlzZWQgYnkgYmlyZGxpZmUgaHR0cDovL2RhdGF6b25lLmJpcmRsaWZlLm9yZy9zcGVjaWVzL2ZhY3RzaGVldC80NTQ0ODE5OSAtIHByZXZpb3VzbHkgbHVtcGVkIGFzIEQuIHBpbm9uCiogUHRpbGlub3B1cyBzdWJndWxhcmlzCSAtIG5vdCBhIHNwZWNpZXMgcmVjb2duaXNlZCBieSBiaXJkbGlmZSBodHRwOi8vZGF0YXpvbmUuYmlyZGxpZmUub3JnL3NwZWNpZXMvZmFjdHNoZWV0LzIyNjkxMzUxCiogUmFtcGhpY3VsdXMgbWVyaWRpb25hbGlzIC0gbm90IGEgc3BlY2llcyByZWNvZ25pc2VkIGJ5IGJpcmRsaWZlIGh0dHA6Ly9kYXRhem9uZS5iaXJkbGlmZS5vcmcvc3BlY2llcy9mYWN0c2hlZXQvMjI3MjgwNDUgLSBwcmV2aW91c2x5IHBsYWNlZCBpbiB0aGUgZ2VudXMgUHRpbGlub3B1cyBhbmQgbHVtcGVkIGFzIFAuIGZpc2NoZXJpCiogU3RpZ21hdG9wZWxpYSBjaGluZW5zaXMgLSBub3QgYSBzcGVjaWVzIHJlY29nbmlzZWQgYnkgYmlyZGxpZmUgaHR0cDovL2RhdGF6b25lLmJpcmRsaWZlLm9yZy9zcGVjaWVzL2ZhY3RzaGVldC9zdGlnbWF0b3BlbGlhLWNoaW5lbnNpcwoKRXh0aW5jdCBzcGVjaWVzOgoqIENhbG9lbmFzIG1hY3VsYXRhCQoqIE5lc29lbmFzIHJvc3RyYXRhCQoqIEdhbGxpY29sdW1iYSBub3Jmb2xjaWVuc2lzCgojIyMgTWlzc2luZyBOZXNvZW5hcyBwaWN0dXJhdGEKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZVtiaXJkbGlmZUNvbHVtYmlkYWUkc3BlY2llc19uYW1lID09ICdOZXNvZW5hcyBwaWN0dXJhdGEnLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVbYmlyZGxpZmUkU0NJX05BTUUgPT0gJ05lc29lbmFzIHBpY3R1cmF0dXMnLF0KYGBgCmBgYHtyfQpiaXJkbGlmZUNvbHVtYmlkYWVbYmlyZGxpZmVDb2x1bWJpZGFlJGJpcmRsaWZlX2lkID09ICcyMjY5MDM2NCcsXQpgYGAKQWxyZWFkeSBwcmVzZW50LCB1cGRhdGUgc3lub255bXMKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZSRzeW5vbnltc1tiaXJkbGlmZUNvbHVtYmlkYWUkYmlyZGxpZmVfaWQgPT0gJzIyNjkwMzY0J10gPSAnQ29sdW1iYSBwaWN0dXJhdGE7IFN0cmVwdG9wZWxpYSBwaWN0dXJhdGEsTmVzb2VuYXMgcGljdHVyYXRhJwpgYGAKCgojIyMgTWlzc2luZyBHZW90cnlnb24gbGF3cmVuY2lpClByZXZpb3VzbHkgY29uc2lkZXJlZCBjb25zcGVjaWZpYyBvZiBaZW50cnlnb24gY2FycmlrZXJpCgpodHRwOi8vZGF0YXpvbmUuYmlyZGxpZmUub3JnL3NwZWNpZXMvZmFjdHNoZWV0LzIyNzI5ODk5CgpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRzcGVjaWVzX25hbWUgPT0gJ0dlb3RyeWdvbiBsYXdyZW5jaWknLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVbYmlyZGxpZmUkU0NJX05BTUUgPT0gJ1plbnRyeWdvbiBjYXJyaWtlcmknLF0KYGBgCmBgYHtyfQpiaXJkbGlmZUNvbHVtYmlkYWVbYmlyZGxpZmVDb2x1bWJpZGFlJGJpcmRsaWZlX2lkID09ICcyMjY5MDkwMScsXQpgYGAKQWxyZWFkeSBwcmVzZW50LCB1cGRhdGUgc3lub255bXMKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZSRzeW5vbnltc1tiaXJkbGlmZUNvbHVtYmlkYWUkYmlyZGxpZmVfaWQgPT0gJzIyNjkwOTAxJ10gPSAnR2VvdHJ5Z29uIGNhcnJpa2VyaSxHZW90cnlnb24gbGF3cmVuY2lpJwpgYGAKCiMjIyBNaXNzaW5nIEdhbGxpY29sdW1iYSBiZWNjYXJpaQpodHRwOi8vZGF0YXpvbmUuYmlyZGxpZmUub3JnL3NwZWNpZXMvZmFjdHNoZWV0LzIyNjkxMDY2CgpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRzcGVjaWVzX25hbWUgPT0gJ0dhbGxpY29sdW1iYSBiZWNjYXJpaScsXQpgYGAKCmBgYHtyfQpiaXJkbGlmZVtiaXJkbGlmZSRTQ0lfTkFNRSA9PSAnUGFtcHVzYW5hIGJlY2NhcmlpJyxdCmBgYApgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnNjA0NDQ3OTInLF0KYGBgCkFscmVhZHkgcHJlc2VudCwgdXBkYXRlIHN5bm9ueW1zCmBgYHtyfQpiaXJkbGlmZUNvbHVtYmlkYWUkc3lub255bXNbYmlyZGxpZmVDb2x1bWJpZGFlJGJpcmRsaWZlX2lkID09ICc2MDQ0NDc5MiddID0gJ0dhbGxpY29sdW1iYSBiZWNjYXJpaScKYGBgCgoKIyMjIE1pc3NpbmcgR2VvcGhhcHMgZmVycnVnaW5lYQpodHRwOi8vZGF0YXpvbmUuYmlyZGxpZmUub3JnL3NwZWNpZXMvZmFjdHNoZWV0LzIyNzI1MTg0IC0gbHVtcGVkIGluIHdpdGggRy4gcGx1bWlmZXJhCgpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRzcGVjaWVzX25hbWUgPT0gJ0dlb3BoYXBzIGZlcnJ1Z2luZWEnLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVbYmlyZGxpZmUkU0NJX05BTUUgPT0gJ0dlb3BoYXBzIHBsdW1pZmVyYScsXQpgYGAKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZVtiaXJkbGlmZUNvbHVtYmlkYWUkYmlyZGxpZmVfaWQgPT0gJzIyNjkwNjgyJyxdCmBgYApBbHJlYWR5IHByZXNlbnQsIHVwZGF0ZSBzeW5vbnltcwpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlJHN5bm9ueW1zW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnMjI2OTA2ODInXSA9ICdHZW9waGFwcyBmZXJydWdpbmVhJwpgYGAKCiMjIyBNaXNzaW5nIER1Y3VsYSBjb25zdGFucwpodHRwOi8vZGF0YXpvbmUuYmlyZGxpZmUub3JnL3NwZWNpZXMvZmFjdHNoZWV0L2R1Y3VsYS1jb25zdGFucwoKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZVtiaXJkbGlmZUNvbHVtYmlkYWUkc3BlY2llc19uYW1lID09ICdEdWN1bGEgY29uc3RhbnMnLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVbYmlyZGxpZmUkU0NJX05BTUUgPT0gJ0R1Y3VsYSBzcGlsb3JyaG9hJyxdCmBgYAoKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZVtiaXJkbGlmZUNvbHVtYmlkYWUkYmlyZGxpZmVfaWQgPT0gJzIyNzMzNTU0JyxdCmBgYApBbHJlYWR5IHByZXNlbnQsIHVwZGF0ZSBzeW5vbnltcwpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlJHN5bm9ueW1zW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnMjI3MzM1NTQnXSA9ICdEdWN1bGEgY29uc3RhbnMnCmBgYAoKIyMjIE1pc3NpbmcgRHVjdWxhIHNhbHZhZG9yaWkKaHR0cDovL2RhdGF6b25lLmJpcmRsaWZlLm9yZy9zcGVjaWVzL2ZhY3RzaGVldC80NTQ0ODE5OSAtIHByZXZpb3VzbHkgbHVtcGVkIGFzIEQuIHBpbm9uCgpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRzcGVjaWVzX25hbWUgPT0gJ0R1Y3VsYSBzYWx2YWRvcmlpJyxdCmBgYAoKYGBge3J9CmJpcmRsaWZlW2JpcmRsaWZlJFNDSV9OQU1FID09ICdEdWN1bGEgcGlub24nLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnMjI2OTE3NjAnLF0KYGBgCgpBbHJlYWR5IHByZXNlbnQsIHVwZGF0ZSBzeW5vbnltcwpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlJHN5bm9ueW1zW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnMjI2OTE3NjAnXSA9ICdEdWN1bGEgc2FsdmFkb3JpaScKYGBgCgojIyMgTWlzc2luZyBQdGlsaW5vcHVzIHN1Ymd1bGFyaXMKaHR0cDovL2RhdGF6b25lLmJpcmRsaWZlLm9yZy9zcGVjaWVzL2ZhY3RzaGVldC8yMjY5MTM1MQoKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZVtiaXJkbGlmZUNvbHVtYmlkYWUkc3BlY2llc19uYW1lID09ICdQdGlsaW5vcHVzIHN1Ymd1bGFyaXMnLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVbYmlyZGxpZmUkU0NJX05BTUUgPT0gJ1JhbXBoaWN1bHVzIHN1Ymd1bGFyaXMnLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnMjI3MjgxNDYnLF0KYGBgCkFscmVhZHkgcHJlc2VudCwgdXBkYXRlIHN5bm9ueW1zCmBgYHtyfQpiaXJkbGlmZUNvbHVtYmlkYWUkc3lub255bXNbYmlyZGxpZmVDb2x1bWJpZGFlJGJpcmRsaWZlX2lkID09ICcyMjcyODE0NiddID0gJ1B0aWxpbm9wdXMgc3ViZ3VsYXJpcycKYGBgCgojIyMgTWlzc2luZyBSYW1waGljdWx1cyBtZXJpZGlvbmFsaXMKaHR0cDovL2RhdGF6b25lLmJpcmRsaWZlLm9yZy9zcGVjaWVzL2ZhY3RzaGVldC8yMjcyODA0NSAtIHByZXZpb3VzbHkgcGxhY2VkIGluIHRoZSBnZW51cyBQdGlsaW5vcHVzIGFuZCBsdW1wZWQgYXMgUC4gZmlzY2hlcmkKCmBgYHtyfQpiaXJkbGlmZUNvbHVtYmlkYWVbYmlyZGxpZmVDb2x1bWJpZGFlJHNwZWNpZXNfbmFtZSA9PSAnUmFtcGhpY3VsdXMgbWVyaWRpb25hbGlzJyxdCmBgYAoKYGBge3J9CmJpcmRsaWZlW2JpcmRsaWZlJFNDSV9OQU1FID09ICdSYW1waGljdWx1cyBmaXNjaGVyaScsXQpgYGAKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZVtiaXJkbGlmZUNvbHVtYmlkYWUkYmlyZGxpZmVfaWQgPT0gJzIyNjkxMzMyJyxdCmBgYApBbHJlYWR5IHByZXNlbnQsIHVwZGF0ZSBzeW5vbnltcwpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlJHN5bm9ueW1zW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnMjI2OTEzMzInXSA9ICdSYW1waGljdWx1cyBtZXJpZGlvbmFsaXMnCmBgYAoKIyMjIE1pc3NpbmcgU3RpZ21hdG9wZWxpYSBjaGluZW5zaXMKYGBge3J9CmJpcmRsaWZlQ29sdW1iaWRhZVtiaXJkbGlmZUNvbHVtYmlkYWUkc3BlY2llc19uYW1lID09ICdTdGlnbWF0b3BlbGlhIGNoaW5lbnNpcycsXQpgYGAKCmBgYHtyfQpiaXJkbGlmZVtiaXJkbGlmZSRTQ0lfTkFNRSA9PSAnU3BpbG9wZWxpYSBjaGluZW5zaXMnLF0KYGBgCgpgYGB7cn0KYmlyZGxpZmVDb2x1bWJpZGFlW2JpcmRsaWZlQ29sdW1iaWRhZSRiaXJkbGlmZV9pZCA9PSAnNjA0ODI4ODcnLF0KYGBgCkFscmVhZHkgcHJlc2VudCwgdXBkYXRlIHN5bm9ueW1zCmBgYHtyfQpiaXJkbGlmZUNvbHVtYmlkYWUkc3lub255bXNbYmlyZGxpZmVDb2x1bWJpZGFlJGJpcmRsaWZlX2lkID09ICc2MDQ4Mjg4NyddID0gJ1N0cmVwdG9wZWxpYSBjaGluZW5zaXMsU3RpZ21hdG9wZWxpYSBjaGluZW5zaXMnCmBgYAoKIyMgU3RvcmUgQmlyZGxpZmUgdGF4b25vbXkKYGBge3J9CndyaXRlX2NzdihiaXJkbGlmZUNvbHVtYmlkYWVbYmlyZGxpZmVDb2x1bWJpZGFlJHNwZWNpZXNfbmFtZSAlaW4lIGJpcmRsaWZlJFNDSV9OQU1FLF0sIGZpbGVuYW1lKEJJUkRMSUZFX1dPUktJTkdfT1VUUFVUX0RJUiwgJ3RheG9ub215LmNzdicpKQpiaXJkbGlmZUNvbHVtYmlkYWUgPSByZWFkX2NzdihmaWxlbmFtZShCSVJETElGRV9XT1JLSU5HX09VVFBVVF9ESVIsICd0YXhvbm9teS5jc3YnKSkKaGVhZChiaXJkbGlmZUNvbHVtYmlkYWUpCmBgYAoKIyMgRmlsdGVyIEJpcmRsaWZlIERpc3RyaWJ1dGlvbnMgdG8gb25seSBDb2x1bWJpZGFlCkRvIHdlIGhhdmUgYW55IGRpc3RyaWJ1dGlvbnMgbm90IGluIG91ciB0YXhvbm9teT8KYGBge3J9CmJpcmRsaWZlWyEoYmlyZGxpZmUkU0NJX05BTUUgJWluJSBiaXJkbGlmZUNvbHVtYmlkYWUkc3BlY2llc19uYW1lKSxdCmBgYAoKYGBge3J9CkNPTFVNQklEQUVfV09STERfRElTVFJJQlVUSU9OUyA9IGZpbGVuYW1lKEJJUkRMSUZFX1dPUktJTkdfT1VUUFVUX0RJUiwgImNvbHVtYmlkYWVfd29ybGQuc2hwIikKd3JpdGVfc2YoYmlyZGxpZmUsIENPTFVNQklEQUVfV09STERfRElTVFJJQlVUSU9OUykKY29sdW1iaWRhZURpc3RyaWJ1dGlvbiA9IHJlYWRfc2YoQ09MVU1CSURBRV9XT1JMRF9ESVNUUklCVVRJT05TKQpgYGAKCgpGcmVlIHVwIG1lbW9yeSBieSByZW1vdmluZyBiaXJkbGlmZSBkYXRhIGZyb20gd29ya3NwYWNlCmBgYHtyfQpybShiaXJkbGlmZSkKcm0oYmlyZGxpZmVUYXhvbm9teSkKcm0oYmlyZGxpZmVUYXhvbm9teV90bXApCnJtKGJpcmRsaWZlVGF4b25vbXlXYikKcm0oYmlyZGxpZmVUYXhvbm9teVdiX1NoZWV0cykKYGBgCgpgYGB7cn0Kc3RfY3JzKGNvbHVtYmlkYWVEaXN0cmlidXRpb24pCmBgYAoKIyBDcmVhdGUgaW50ZXJzZWN0aW9uIG9mIENvbHVtYmlkYWUgRGlzdHJpYnV0aW9ucyB3aXRoIFVyYmFuIFNwYWNlcwpSZWFkIGluIG91ciBpbml0aWFsIGNpdHkgdmVjdG9ycywgd2Ugd2lsbCBqb2luIHRoZXNlIHRvIG91ciBjaGVja2xpc3RzCmBgYHtyfQppbml0aWFsX2NpdHlfc2VsZWN0aW9uID0gcmVhZF9zZihmaWxlbmFtZShta2RpcihHRU9fV09SS0lOR19PVVRQVVRfRElSLCAnY2l0aWVzJyksICdpbml0aWFsX3NlbGVjdGlvbi5zaHAnKSkKYGBgCgpgYGB7cn0Kc3RfY3JzKGluaXRpYWxfY2l0eV9zZWxlY3Rpb24pCmBgYAoKYGBge3J9CnNmOjpzZl91c2VfczIoRkFMU0UpCgp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMgPSBzdF9qb2luKGluaXRpYWxfY2l0eV9zZWxlY3Rpb24sIGNvbHVtYmlkYWVEaXN0cmlidXRpb24pIAoKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zCmBgYAoKIyMgQ2hlY2sgYmlyZGxpZmUgZGlzdHJpYnV0aW9uIGRhdGEKClNwZWNpZXMgd2l0aCB1bmtub3duIHByZXNlbmNlPwpgYGB7cn0KdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zW3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRQUkVTRU5DRSA+IDUsIGMoJ1NDSV9OQU1FJywgJ2NpdHlfbmFtZScsICdjaXR5X2lkJyldCmBgYAoKCkFueSBleHRpbmN0IHNwZWNpZXM/CmBgYHtyfQp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnNbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFBSRVNFTkNFID09IDUsIGMoJ1NDSV9OQU1FJywgJ2NpdHlfbmFtZScsICdjaXR5X2lkJyldCmBgYAoKUG9zc2libHkgRXh0aW5jdCBzcGVjaWVzCmBgYHtyfQp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnNbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFBSRVNFTkNFID09IDQsIGMoJ1NDSV9OQU1FJywgJ2NpdHlfbmFtZScsICdjaXR5X2lkJyldCmBgYAoKIyMgTWFwIHNlYXNvbmFsIGFuZCBvcmlnaW4gdG8gc3RyaW5nIHZhbHVlcwpgYGB7cn0KdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJHNlYXNvbmFsX2Rlc2MgPSAiVW5rbm93biBDb2RlIgp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkc2Vhc29uYWxfZGVzY1t1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkU0VBU09OQUwgPT0gIjEiXSA9ICJSZXNpZGVudCIKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJHNlYXNvbmFsX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFNFQVNPTkFMID09ICIyIl0gPSAiQnJlZWRpbmcgU2Vhc29uIiAKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJHNlYXNvbmFsX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFNFQVNPTkFMID09ICIzIl0gPSAiTm9uLWJyZWVkaW5nIFNlYXNvbiIgCnVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRzZWFzb25hbF9kZXNjW3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRTRUFTT05BTCA9PSAiNCJdID0gIlBhc3NhZ2UiIAp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkc2Vhc29uYWxfZGVzY1t1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkU0VBU09OQUwgPT0gIjUiXSA9ICJTZWFzb25hbCBvY2N1cmVuY2UgdW5jZXJ0YWluIgpgYGAKCmBgYHtyfQp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkb3JpZ2luX2Rlc2MgPSAiVW5rbm93biBDb2RlIgp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkb3JpZ2luX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJE9SSUdJTiA9PSAiMSJdID0gIk5hdGl2ZSIKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJG9yaWdpbl9kZXNjW3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRPUklHSU4gPT0gIjIiXSA9ICJSZWludHJvZHVjZWQiIAp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkb3JpZ2luX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJE9SSUdJTiA9PSAiMyJdID0gIkludHJvZHVjZWQiIAp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkb3JpZ2luX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJE9SSUdJTiA9PSAiNCJdID0gIlZhZ3JhbnQiIAp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkb3JpZ2luX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJE9SSUdJTiA9PSAiNSJdID0gIk9yaWdpbiBVbmNlcnRhaW4iCnVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRvcmlnaW5fZGVzY1t1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkT1JJR0lOID09ICI2Il0gPSAiQXNzaXN0ZWQgQ29sb25pc2F0aW9uIgpgYGAKCmBgYHtyfQp1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkcHJlc2VuY2VfZGVzYyA9ICJVbmtub3duIENvZGUiCnVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRwcmVzZW5jZV9kZXNjW3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRQUkVTRU5DRSA9PSAiMSJdID0gIkV4dGFudCIKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJHByZXNlbmNlX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFBSRVNFTkNFID09ICIyIl0gPSAiUHJvYmFibHkgRXh0YW50IiAKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJHByZXNlbmNlX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFBSRVNFTkNFID09ICIzIl0gPSAiUG9zc2libHkgRXh0YW50IiAKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJHByZXNlbmNlX2Rlc2NbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFBSRVNFTkNFID09ICI0Il0gPSAiUG9zc2libHkgRXh0aW5jdCIgCnVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRwcmVzZW5jZV9kZXNjW3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRQUkVTRU5DRSA9PSAiNSJdID0gIkV4dGluY3QiCnVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRwcmVzZW5jZV9kZXNjW3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRQUkVTRU5DRSA9PSAiNiJdID0gIlByZXNlbmNlIFVuY2VydGFpbiIKYGBgCgpgYGB7cn0KY2FjaGVfdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zID0gZmlsZW5hbWUoQklSRExJRkVfV09SS0lOR19PVVRQVVRfRElSLCAndXJiYW5fZGlzdHJpYnV0aW9uc19iaXJkbGlmZV9vbmx5LmNzdicpCndyaXRlX2Nzdih1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMsIGNhY2hlX3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucykKdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zID0gcmVhZF9jc3YoY2FjaGVfdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zKQpgYGAKCiMjIE1pc3NpbmcgTm9ydGggQW1lcmljYW4gZGlzdHJpYnV0aW9uIG9mIFN0cmVwdG9wZWxpYSBkZWNhb2N0byBhbmQgQ29sdW1iYSBMaXZpYQpCaXJkbGlmZSBpcyBtaXNzaW5nIHRoZSByZWNlbnQgaW52YXNpb24gb2YgU3RyZXB0b3BlbGlhIGRlY2FvY3RvIGludG8gTm9ydGggQW1lcmljYS4gCldlIHN1cHBsZW1lbnQgdGhlIGRhdGEgZm9yIFN0cmVwdG9wZWxpYSBkZWNhb2N0byB3aXRoIHRoZSByYW5nZSBmcm9tIGVCaXJkJ3MgU3RhdHVzIGFuZCBUcmVuZHMgZGF0YXNldC4KClRoaXMgZGF0YSBjYW4gYmUgZG93bmxvYWRlZCBoZXJlOgpodHRwczovL3NjaWVuY2UuZWJpcmQub3JnL2VuL3N0YXR1cy1hbmQtdHJlbmRzL3NwZWNpZXMvZXVjZG92L2Rvd25sb2FkcwoKVGhlIGNvdW50cnkgYm91bmRhbmRhcmllcyBjYW4gYmUgZG93bmxvYWRlZCBmcm9tIHRoZSB3b3JsZCBiYW5rIGhlcmU6Cmh0dHBzOi8vZGF0YWNhdGFsb2cud29ybGRiYW5rLm9yZy9zZWFyY2gvZGF0YXNldC8wMDM4MjcyL1dvcmxkLUJhbmstT2ZmaWNpYWwtQm91bmRhcmllcwoKYGBge3J9CkNPVU5UUllfQk9VTkRBUklFUyA9ICcvVXNlcnMvamFtZXMvRHJvcGJveC9QaEQvV29ybGRCYW5rX2NvdW50cmllc19BZG1pbjBfMTBtL1dCX2NvdW50cmllc19BZG1pbjBfMTBtLnNocCcKd29ybGRfbWFwID0gc3Rfc2ltcGxpZnkoc3RfcmVhZChDT1VOVFJZX0JPVU5EQVJJRVMpLCBkVG9sZXJhbmNlID0gMC4wMikKYGBgCiMjIyBDb2xsYXJlZCBEb3ZlCkV4aXN0aW5nIHJhbmdlIGZyb20gQmlyZGxpZmUKYGBge3J9CnNmOjpzZl91c2VfczIoRkFMU0UpCmNvbGRvdl92ZWN0ID0gc3Rfc2ltcGxpZnkoY29sdW1iaWRhZURpc3RyaWJ1dGlvbltjb2x1bWJpZGFlRGlzdHJpYnV0aW9uJFNDSV9OQU1FID09ICdTdHJlcHRvcGVsaWEgZGVjYW9jdG8nLCBjKCdQUkVTRU5DRScpXSwgZFRvbGVyYW5jZSA9IDAuMDIpCgpnZ3Bsb3QoKSArICAKICBnZW9tX3NmKGRhdGEgPSB3b3JsZF9tYXAsIGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSkgKwogIGdlb21fc2YoZGF0YSA9IGNvbGRvdl92ZWN0LCBhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksIGZpbGwgPSAicmVkIikKYGBgCgpSYW5nZSBmcm9tIGVCaXJkCmBgYHtyfQpFQklSRF9FVUNET1ZfUkFOR0UgPSAnL1VzZXJzL2phbWVzL0Ryb3Bib3gvUGhEL2VCaXJkL2V1Y2Rvdl9yYW5nZV8yMDIyL2V1Y2Rvdl9yYW5nZV8yMDIyLmdwa2cnCmV1Y2Rvdl9yYW5nZV92ZWN0ID0gc3RfcmVhZChFQklSRF9FVUNET1ZfUkFOR0UpCgpnZ3Bsb3QoKSArICAKICBnZW9tX3NmKGRhdGEgPSB3b3JsZF9tYXAsIGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSkgKwogIGdlb21fc2YoZGF0YSA9IGV1Y2Rvdl9yYW5nZV92ZWN0WyJzY2llbnRpZmljX25hbWUiXSwgYWVzKGdlb21ldHJ5ID0gZ2VvbSksIGZpbGwgPSAicmVkIikKYGBgCgpFeHRyYWN0IGNpdGllcyBmcm9tIGVCaXJkIHJhbmdlCmBgYHtyfQpzZjo6c2ZfdXNlX3MyKEZBTFNFKQoKZXhpc3RpbmdfZXVjZG92X2NpdGllcyA9IHVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRjaXR5X2lkW3VyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRTQ0lfTkFNRSA9PSAnU3RyZXB0b3BlbGlhIGRlY2FvY3RvJ10KCmV1Y2Rvdl9kaXN0cmlidXRpb24gPSBzdF9qb2luKGluaXRpYWxfY2l0eV9zZWxlY3Rpb24sIGV1Y2Rvdl9yYW5nZV92ZWN0KSAKCmV1Y2Rvdl9kaXN0cmlidXRpb25bIWlzLm5hKGV1Y2Rvdl9kaXN0cmlidXRpb24kc3BlY2llc19jb2RlKSAmICEoZXVjZG92X2Rpc3RyaWJ1dGlvbiRjaXR5X2lkICVpbiUgZXhpc3RpbmdfZXVjZG92X2NpdGllcyksXQpgYGAKCgpgYGB7cn0KbWlzc2luZ19ldWNkb3ZfY2l0aWVzID0gZGF0YS5mcmFtZSgKICAgIHNwZWNpZXNfbmFtZSA9ICdTdHJlcHRvcGVsaWEgZGVjYW9jdG8nLCAKICAgIGNpdHlfaWQgPSBldWNkb3ZfZGlzdHJpYnV0aW9uJGNpdHlfaWRbIWlzLm5hKGV1Y2Rvdl9kaXN0cmlidXRpb24kc3BlY2llc19jb2RlKSAmICEoZXVjZG92X2Rpc3RyaWJ1dGlvbiRjaXR5X2lkICVpbiUgZXhpc3RpbmdfZXVjZG92X2NpdGllcyldLAogICAgY2l0eV9uYW1lPSBldWNkb3ZfZGlzdHJpYnV0aW9uJGNpdHlfbmFtZVshaXMubmEoZXVjZG92X2Rpc3RyaWJ1dGlvbiRzcGVjaWVzX2NvZGUpICYgIShldWNkb3ZfZGlzdHJpYnV0aW9uJGNpdHlfaWQgJWluJSBleGlzdGluZ19ldWNkb3ZfY2l0aWVzKV0sCiAgICBvcmlnaW4gPSAnSW50cm9kdWNlZCcsCiAgICBzZWFzb25hbCA9ICdSZXNpZGVudCcsCiAgICBwcmVzZW5jZSA9ICdFeHRhbnQnCikKbWlzc2luZ19ldWNkb3ZfY2l0aWVzCmBgYAoKIyMjIFJvY2sgZG92ZQpFeGlzdGluZyByYW5nZSBmcm9tIEJpcmRsaWZlCmBgYHtyfQpzZjo6c2ZfdXNlX3MyKEZBTFNFKQpyb2Nkb3ZfdmVjdCA9IHN0X3NpbXBsaWZ5KGNvbHVtYmlkYWVEaXN0cmlidXRpb25bY29sdW1iaWRhZURpc3RyaWJ1dGlvbiRTQ0lfTkFNRSA9PSAnQ29sdW1iYSBsaXZpYScsIGMoJ1BSRVNFTkNFJyldLCBkVG9sZXJhbmNlID0gMC4wMikKCmdncGxvdCgpICsgIAogIGdlb21fc2YoZGF0YSA9IHdvcmxkX21hcCwgYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSArCiAgZ2VvbV9zZihkYXRhID0gcm9jZG92X3ZlY3QsIGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwgZmlsbCA9ICJyZWQiKQpgYGAKClJhbmdlIGZyb20gZUJpcmQKYGBge3J9CkVCSVJEX1JPQ1BJR19SQU5HRSA9ICcvVXNlcnMvamFtZXMvRHJvcGJveC9QaEQvZUJpcmQvcm9jcGlnX3JhbmdlXzIwMjIvcm9jcGlnX3JhbmdlXzIwMjIuZ3BrZycKcm9jcGlnX3JhbmdlX3ZlY3QgPSBzdF9yZWFkKEVCSVJEX1JPQ1BJR19SQU5HRSkKZ2dwbG90KCkgKyAgCiAgZ2VvbV9zZihkYXRhID0gd29ybGRfbWFwLCBhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSkpICsKICBnZW9tX3NmKGRhdGEgPSByb2NwaWdfcmFuZ2VfdmVjdFsic2NpZW50aWZpY19uYW1lIl0sIGFlcyhnZW9tZXRyeSA9IGdlb20pLCBmaWxsID0gInJlZCIpCmBgYAoKYGBge3J9CnNmOjpzZl91c2VfczIoRkFMU0UpCgpleGlzdGluZ19yb2NwaWdfY2l0aWVzID0gdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJGNpdHlfaWRbdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFNDSV9OQU1FID09ICdDb2x1bWJhIGxpdmlhJ10KCnJvY3BpZ19kaXN0cmlidXRpb24gPSBzdF9qb2luKGluaXRpYWxfY2l0eV9zZWxlY3Rpb24sIHJvY3BpZ19yYW5nZV92ZWN0KSAKCnJvY3BpZ19kaXN0cmlidXRpb25bIWlzLm5hKHJvY3BpZ19kaXN0cmlidXRpb24kc3BlY2llc19jb2RlKSAmICEocm9jcGlnX2Rpc3RyaWJ1dGlvbiRjaXR5X2lkICVpbiUgZXhpc3Rpbmdfcm9jcGlnX2NpdGllcyksXQpgYGAKCmBgYHtyfQptaXNzaW5nX3JvY3BpZ19jaXRpZXMgPSBkYXRhLmZyYW1lKAogICAgc3BlY2llc19uYW1lID0gJ0NvbHVtYmEgbGl2aWEnLCAKICAgIGNpdHlfaWQgPSByb2NwaWdfZGlzdHJpYnV0aW9uJGNpdHlfaWRbIWlzLm5hKHJvY3BpZ19kaXN0cmlidXRpb24kc3BlY2llc19jb2RlKSAmICEocm9jcGlnX2Rpc3RyaWJ1dGlvbiRjaXR5X2lkICVpbiUgZXhpc3Rpbmdfcm9jcGlnX2NpdGllcyldLAogICAgY2l0eV9uYW1lPSByb2NwaWdfZGlzdHJpYnV0aW9uJGNpdHlfbmFtZVshaXMubmEocm9jcGlnX2Rpc3RyaWJ1dGlvbiRzcGVjaWVzX2NvZGUpICYgIShyb2NwaWdfZGlzdHJpYnV0aW9uJGNpdHlfaWQgJWluJSBleGlzdGluZ19yb2NwaWdfY2l0aWVzKV0sCiAgICBvcmlnaW4gPSAnSW50cm9kdWNlZCcsCiAgICBzZWFzb25hbCA9ICdSZXNpZGVudCcsCiAgICBwcmVzZW5jZSA9ICdFeHRhbnQnCikKbWlzc2luZ19yb2NwaWdfY2l0aWVzCmBgYAoKIyMgQWRkIFNwb3R0ZWQgZG92ZSdzIGV4cGFuZGVkIHJhbmdlIGludG8gQ2hpbmEKRXhpc3RpbmcgcmFuZ2UgZnJvbSBCaXJkbGlmZQpgYGB7cn0Kc2Y6OnNmX3VzZV9zMihGQUxTRSkKc3BvZG92X3ZlY3QgPSBzdF9zaW1wbGlmeShjb2x1bWJpZGFlRGlzdHJpYnV0aW9uW2NvbHVtYmlkYWVEaXN0cmlidXRpb24kU0NJX05BTUUgJWluJSBjKCdTcGlsb3BlbGlhIGNoaW5lbnNpcycsJ1NwaWxvcGVsaWEgc3VyYXRlbnNpcycsJ1BhdGFnaW9lbmFzIGFsYmlwZW5uaXMnKSwgYygnU0NJX05BTUUnKV0sIGRUb2xlcmFuY2UgPSAwLjAyKQoKZ2dwbG90KCkgKyAgCiAgZ2VvbV9zZihkYXRhID0gd29ybGRfbWFwLCBhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSkpICsKICBnZW9tX3NmKGRhdGEgPSBzcG9kb3ZfdmVjdCwgYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnksIGZpbGwgPSBTQ0lfTkFNRSkpCmBgYAoKUmFuZ2UgZnJvbSBlQmlyZApgYGB7cn0KRUJJUkRfU1BPRE9WX1JBTkdFID0gJy9Vc2Vycy9qYW1lcy9Ecm9wYm94L1BoRC9lQmlyZC9zcG9kb3ZfcmFuZ2VfMjAyMi9zcG9kb3ZfcmFuZ2VfMjAyMi5ncGtnJwpzcG9kb3ZfcmFuZ2VfdmVjdCA9IHN0X3JlYWQoRUJJUkRfU1BPRE9WX1JBTkdFKQpnZ3Bsb3QoKSArICAKICBnZW9tX3NmKGRhdGEgPSB3b3JsZF9tYXAsIGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSkgKwogIGdlb21fc2YoZGF0YSA9IHNwb2Rvdl9yYW5nZV92ZWN0WyJzY2llbnRpZmljX25hbWUiXSwgYWVzKGdlb21ldHJ5ID0gZ2VvbSksIGZpbGwgPSAicmVkIikKYGBgCgpgYGB7cn0Kc2Y6OnNmX3VzZV9zMihGQUxTRSkKCmV4aXN0aW5nX3Nwb2Rvdl9jaXRpZXMgPSB1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkY2l0eV9pZFt1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkU0NJX05BTUUgJWluJSBjKCdTcGlsb3BlbGlhIGNoaW5lbnNpcycsJ1NwaWxvcGVsaWEgc3VyYXRlbnNpcycsJ1BhdGFnaW9lbmFzIGFsYmlwZW5uaXMnKV0KCnNwb2Rvdl9kaXN0cmlidXRpb24gPSBzdF9qb2luKGluaXRpYWxfY2l0eV9zZWxlY3Rpb24sIHNwb2Rvdl9yYW5nZV92ZWN0KSAKCnNwb2Rvdl9kaXN0cmlidXRpb25bIWlzLm5hKHNwb2Rvdl9kaXN0cmlidXRpb24kc3BlY2llc19jb2RlKSAmICEoc3BvZG92X2Rpc3RyaWJ1dGlvbiRjaXR5X2lkICVpbiUgZXhpc3Rpbmdfc3BvZG92X2NpdGllcyksXQpgYGAKCmBgYHtyfQptaXNzaW5nX3Nwb2Rvdl9jaXRpZXMgPSBkYXRhLmZyYW1lKAogICAgc3BlY2llc19uYW1lID0gJ1NwaWxvcGVsaWEgY2hpbmVuc2lzJywgCiAgICBjaXR5X2lkID0gc3BvZG92X2Rpc3RyaWJ1dGlvbiRjaXR5X2lkWyFpcy5uYShzcG9kb3ZfZGlzdHJpYnV0aW9uJHNwZWNpZXNfY29kZSkgJiAhKHNwb2Rvdl9kaXN0cmlidXRpb24kY2l0eV9pZCAlaW4lIGV4aXN0aW5nX3Nwb2Rvdl9jaXRpZXMpXSwKICAgIGNpdHlfbmFtZT0gc3BvZG92X2Rpc3RyaWJ1dGlvbiRjaXR5X25hbWVbIWlzLm5hKHNwb2Rvdl9kaXN0cmlidXRpb24kc3BlY2llc19jb2RlKSAmICEoc3BvZG92X2Rpc3RyaWJ1dGlvbiRjaXR5X2lkICVpbiUgZXhpc3Rpbmdfc3BvZG92X2NpdGllcyldLAogICAgb3JpZ2luID0gJ0ludHJvZHVjZWQnLAogICAgc2Vhc29uYWwgPSAnUmVzaWRlbnQnLAogICAgcHJlc2VuY2UgPSAnRXh0YW50JwopCm1pc3Npbmdfc3BvZG92X2NpdGllcwpgYGAKCiMjIFN0b3JlIHJlZ2lvbmFsIHBvb2wgcmVzdWx0CmBgYHtyfQp1cmJhbl9kaXN0cmlidXRpb24gPSByYmluZCgKICBkYXRhLmZyYW1lKAogICAgc3BlY2llc19uYW1lID0gdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJFNDSV9OQU1FLCAKICAgIGNpdHlfaWQgPSB1cmJhbl9jb2x1bWJpZGFlX2Rpc3RyaWJ1dGlvbnMkY2l0eV9pZCwKICAgIGNpdHlfbmFtZT0gdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJGNpdHlfbmFtZSwKICAgIG9yaWdpbiA9IHVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRvcmlnaW5fZGVzYywKICAgIHNlYXNvbmFsID0gdXJiYW5fY29sdW1iaWRhZV9kaXN0cmlidXRpb25zJHNlYXNvbmFsX2Rlc2MsCiAgICBwcmVzZW5jZSA9IHVyYmFuX2NvbHVtYmlkYWVfZGlzdHJpYnV0aW9ucyRwcmVzZW5jZV9kZXNjCiAgKSwKIHJiaW5kKG1pc3NpbmdfZXVjZG92X2NpdGllcywgcmJpbmQobWlzc2luZ19yb2NwaWdfY2l0aWVzLCBtaXNzaW5nX3Nwb2Rvdl9jaXRpZXMpKQopCmBgYAoKYGBge3J9CkJJUkRMSUZFX1VSQkFOX0RJU1RSSUJVVElPTiA9IGZpbGVuYW1lKEJJUkRMSUZFX1dPUktJTkdfT1VUUFVUX0RJUiwgJ3VyYmFuX2Rpc3RyaWJ1dGlvbnMuY3N2JykKd3JpdGVfY3N2KHVyYmFuX2Rpc3RyaWJ1dGlvbiwgQklSRExJRkVfVVJCQU5fRElTVFJJQlVUSU9OKQpgYGAKCiMjIEV4YW1pbmUgcmVzdWx0CmBgYHtyfQp1cmJhbl9kaXN0cmlidXRpb24gPSByZWFkX2NzdihCSVJETElGRV9VUkJBTl9ESVNUUklCVVRJT04pCmBgYAoKU3BlY2llcyBpbiBNYW5jaGVzdGVyJ3MgcmVnaW9uYWwgcG9vbApgYGB7cn0KdXJiYW5fZGlzdHJpYnV0aW9uICU+JSBmaWx0ZXIoY2l0eV9uYW1lID09ICdNYW5jaGVzdGVyJykgCmBgYAoKU3BlY2llcyBpbiBNaWFtaSdzIHJlZ2lvbmFsIHBvb2wKYGBge3J9CnVyYmFuX2Rpc3RyaWJ1dGlvbiAlPiUgZmlsdGVyKGNpdHlfbmFtZSA9PSAnTWlhbWknKSAKYGBgCgpDaXRpZXMgd2l0aCBDb21tb24gV29vZHBpZ2VvbiBpbiByZWdpb25hbCBwb29sCmBgYHtyfQp1cmJhbl9kaXN0cmlidXRpb24gJT4lIGZpbHRlcihzcGVjaWVzX25hbWUgPT0gJ0NvbHVtYmEgcGFsdW1idXMnKQpgYGAKCkNpdGllcyB3aXRoIENvbGxhcmVkIERvdmUgaW4gcmVnaW9uYWwgcG9vbApgYGB7cn0KdXJiYW5fZGlzdHJpYnV0aW9uICU+JSBmaWx0ZXIoc3BlY2llc19uYW1lID09ICdTdHJlcHRvcGVsaWEgZGVjYW9jdG8nKQpgYGAKClJlZ2lvbmFsIHBvb2wgc2l6ZXMKYGBge3J9CnVyYmFuX2Rpc3RyaWJ1dGlvbiAlPiUgZ3JvdXBfYnkoY2l0eV9pZCwgY2l0eV9uYW1lKSAlPiUgc3VtbWFyaXNlKHBvb2xfc2l6ZSA9IG4oKSkgJT4lIGFycmFuZ2UocG9vbF9zaXplKQpgYGAKCg==